package whf.framework.aop;

import java.lang.reflect.Method;
import java.util.Collection;

import org.springframework.aop.AfterReturningAdvice;

import whf.framework.config.ApplicationConfig;
import whf.framework.entity.Entity;
import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.log.entity.Logable;
import whf.framework.log.util.LogUtil;
import whf.framework.meta.Metaable;
import whf.framework.security.entity.User;
import whf.framework.service.Service;
import whf.framework.util.ThreadContext;

/**
 * @author wanghaifeng
 *
 */
public class MethodAfterAdvice implements AfterReturningAdvice {
	private static Log log = LogFactory.getLog(MethodAfterAdvice.class);
	
	/* (non-Javadoc)
	 * @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
	 */
	public void afterReturning(Object object, Method method, Object[] args,
			Object target) throws Throwable {
		if(target instanceof Service){
			long consumeTime = System.currentTimeMillis() - MethodBeforeAdvice.threadLocal.get();
			User user = ThreadContext.getUserInUserContext();
			String sessionId = ThreadContext.getSessionId();
			String department = user ==null? null:user.getDept() == null?null: user.getDept().getCode();
			String operator = user == null?"anonymous":user.getName()+"("+user.getUsername()+")";
			String ip = ThreadContext.getUserContext() != null? ThreadContext.getUserContext().getRemoteIpAddress(): null;
			if(ApplicationConfig.getInstance().isServiceMonitoring() && 
					!(target instanceof Logable) && !(target instanceof Metaable)) {
				String params = null;
				if(args != null) {
					StringBuilder sb = new StringBuilder();
					for(int i=0; i< args.length; i++) {
						sb.append("{").append(i).append("::::");
						if(args[i] == null) {
							sb.append("null");
						} else {
							sb.append(args[i].getClass().getName()).append(":");
							if(args[i] instanceof Entity) {
								Entity en = (Entity)args[i];
								try{
									sb.append(en.getId()).append("-").append(en.getName()).append("-").append(en.getCode());
								}catch(org.hibernate.LazyInitializationException e){ 
									sb.append(en.getClass().getName());
								}
							} else {
								sb.append(args[i].toString());
							}
						}
						sb.append("}; ");
					}
					params = sb.toString();
				}
				whf.framework.log.entity.Log logEntity = new whf.framework.log.entity.Log(department, operator, 
						target.getClass().getSuperclass().getName(), "SERVICE INVOKE", method.getName(), params,
						sessionId, ip, consumeTime, null);
				LogUtil.log(logEntity);
			}
			if(object != null)
				log.debug("Method:" + consumeTime + " -\t" + operator + " - \t" + target.getClass().getName() +":"+object.getClass().getName()+"->"+method.getName());
			else
				log.debug("Method:" + consumeTime + " -\t" + operator + " - \t" + target.getClass().getName()+"->"+method.getName());
		}
	}

}
